<!-- 
  PCS功率与电量图表组件
  该组件用于显示PCS（Power Conversion System）的功率和电量数据
  包含功能：
  1. 双Y轴图表展示：左侧功率，右侧电量
  2. 实时数据统计展示
  3. 自适应布局
  4. 深色/浅色主题支持
-->
<template>
  <n-card
    :bordered="false"
    :class="{ 'dark-theme': darkTheme }"
    class="pcs-chart-card"
  >
    <template #header>
      <div class="chart-header" v-if="showHeader">
        <n-text :depth="1" style="font-size: 10px">{{ title }}</n-text>
        <div class="chart-legend">
          <n-space>
            <n-tag :bordered="false" style="font-size: 10px" :color="{ color: powerLineColor + '20', textColor: powerLineColor }">
              <template #icon>
                <div class="legend-dot" :style="{ background: powerLineColor }"></div>
              </template>
              功率
            </n-tag>
            <n-tag :bordered="false"  style="font-size: 10px" :color="{ color: energyBarColor + '20', textColor: energyBarColor }">
              <template #icon>
                <div class="legend-dot" :style="{ background: energyBarColor }"></div>
              </template>
              电量
            </n-tag>
          </n-space>
        </div>
      </div>
    </template>

    <div ref="chartContainer" class="chart-container" :style="{ width: '100%', height: '100%' }"></div>

    <template #action v-if="showStats">
      <n-grid :cols="3" :x-gap="12">
        <n-grid-item>
          <n-statistic label="当前功率">
            <n-number-animation
              ref="powerAnimation"
              :from="0"
              :to="props.powerData[props.powerData.length - 1] || 0"
              :duration="1000"
              :precision="2"
            >
              <template #suffix>{{ powerUnit }}</template>
            </n-number-animation>
          </n-statistic>
        </n-grid-item>
        <n-grid-item>
          <n-statistic label="累计电量">
            <n-number-animation
              ref="energyAnimation"
              :from="0"
              :to="props.energyData[props.energyData.length - 1] || 0"
              :duration="1000"
              :precision="2"
            >
              {{ props.energyData[props.energyData.length - 1] || 0 }} {{ energyUnit }}
            </n-number-animation>
          </n-statistic>
        </n-grid-item>
        <n-grid-item>
          <n-statistic label="运行状态">
            <n-tag :bordered="false" :color="getColor">
              {{ getStatus }}
            </n-tag>
          </n-statistic>
        </n-grid-item>
      </n-grid>
    </template>
  </n-card>
</template>

<script setup>
// 导入必要的Vue组合式API和D3库
import { ref, onMounted, onBeforeUnmount, watch, nextTick, defineProps, computed } from 'vue';
import * as d3 from 'd3';

// 组件属性定义
const props = defineProps({
  // 基础配置项
  title: {
    type: String,
    default: 'PCS功率与电量' // 图表标题
  },
  showHeader: {
    type: Boolean,
    default: true // 控制是否显示图表头部
  },
  showStats: {
    type: Boolean,
    default: true // 控制是否显示统计数据
  },
  darkTheme: {
    type: Boolean,
    default: true // 控制深色/浅色主题
  },
  chartWidth: {
    type: String,
    default: '100%' // 图表宽度
  },
  chartHeight: {
    type: String,
    default: '100%' // 图表高度
  },
  // 数据配置
  powerData: {
    type: Array,
    default: () => [800,990,1010,1210,2110  ,2300,2200,2000,1900,1800  ,1700,1600,1500,1400,1300,   1200,1100,1000,900,800,   400,300,200,100] // 功率数据默认值
  },
  energyData: {
    type: Array,
    default: () => [1,1.1,1.2,1.3,2 ,2.3,2.3,2,1.9,1.9, 1.7,1.6,1.5,1.4,1.3, 1.2,1.1,1,0.8,0.9, 0.42,0.32,0.2,0.13] // 电量数据默认值
  }, 
  timeData: {
    type: Array,
    default: () => ['00:00','01:00', '02:00','03:00','04:00', '05:00', '06:00', '07:00', '08:00', '09:00', '10:00', '11:00', '12:00', '18:00', '19:00', '20:00', '21:00', '22:00', '23:00'] // 时间轴数据
  },
  // 单位设置
  powerUnit: {
    type: String,
    default: 'W' // 功率单位
  },
  energyUnit: {
    type: String,
    default: 'kWh' // 电量单位
  },
  // 功率线条样式配置
  powerLineColor: {
    type: String,
    default: ' #00FF00', // 功率线颜色 - 这里设置功率曲线的颜色
    description: '功率曲线的颜色，支持任何合法的CSS颜色值'
  },
  powerLineWidth: {
    type: [String, Number],
    default: 2 // 功率线宽度
  },
  powerLineType: {
    type: String,
    default: 'dashed' // 功率线类型
  },
  // 电量柱状图样式配置
  energyBarColor: {
    type: String,
    default: '#2080F0' // 电量柱状图颜色
  },
  energyBarBorderRadius: {
    type: [String, Number],
    default: 0 // 电量柱状图圆角
  },
  // 状态颜色配置
  chargingColor: {
    type: String,
    default: '#18A058' // 充电状态颜色
  },
  dischargingColor: {
    type: String,
    default: '#D03050' // 放电状态颜色
  },
  idleColor: {
    type: String,
    default: '#747A8C' // 待机状态颜色
  },
  // 图表效果
  showGradient: {
    type: Boolean,
    default: true // 是否显示渐变效果
  },
  enableAnimation: {
    type: Boolean,
    default: true // 是否启用动画
  },
  animationDuration: {
    type: [String, Number],
    default: 1000 // 动画持续时间
  },
  smooth: {
    type: Boolean,
    default: true // 是否平滑滚动
  },
  // 字体大小设置
  axisFontSize: {
    type: Number,
    default: 8,
    description: '坐标轴刻度值字体大小'
  },
  leftAxisTextColor: {
    type: String,
    default: '#666666',
    description: '左侧Y轴文本颜色'
  },
  rightAxisTextColor: {
    type: String,
    default: '#666666',
    description: '右侧Y轴文本颜色'
  },
  bottomAxisTextColor: {
    type: String,
    default: '#666666',
    description: '底部X轴文本颜色'
  },
  // 提示框样式配置
  tooltipBgColor: {
    type: String,
    default: 'rgb(58, 67, 194, 0.6)' // 提示框背景色
  },
  tooltipBorderRadius: {
    type: Number,
    default: 4 // 提示框圆角
  },
  tooltipWidth: {
    type: Number,
    default: 80 // 提示框宽度
  },
  tooltipHeight: {
    type: Number,
    default: 40 // 提示框高度
  },
  tooltipTextColor: {
    type: String,
    default: '#fff' // 提示框文字颜色
  },
  tooltipFontSize: {
    type: Number,
    default: 9 // 提示框文字大小
  },
  tooltipPadding: {
    type: Number,
    default: 5 // 提示框内边距
  },
  tooltipLineHeight: {
    type: Number,
    default: 10 // 提示框文字行高
  },
  mouseLineColor: {
    type: String,
    default: 'green',
    description: '悬浮提示文字颜色'
  },
})

// 组件内部变量定义
const chartContainer = ref(null)

// 安全获取数组最后一个值的工具函数
const safeGetLastValue = (data) => {
  return Array.isArray(data) && data.length > 0 ? data[data.length - 1] : 0;
};

// 计算当前状态颜色
const getColor = computed(() => {
  const value = safeGetLastValue(props.powerData);
  if (value > 0) return props.chargingColor;  // 充电状态
  if (value < 0) return props.dischargingColor;  // 放电状态
  return props.idleColor;  // 待机状态
});

// 计算当前运行状态文本
const getStatus = computed(() => {
  const value = safeGetLastValue(props.powerData);
  if (value > 0) return '充电';
  if (value < 0) return '放电';
  return '待机';
})

// 初始化D3图表
const initD3Chart = () => {
  // 清除之前的图表
  d3.select(chartContainer.value).selectAll('*').remove();

  const containerWidth = chartContainer.value.clientWidth;
  const containerHeight = chartContainer.value.clientHeight;

  // 设置图表边距（使用相对值）
  const margin = {
    top: containerHeight * 0.05,     // 5% of height
    right: containerWidth * 0.11,    // 5% of width
    bottom: containerHeight * 0.1,  // 8% of height
    left: containerWidth * 0.11      // 5% of width
  };

  const width = containerWidth - margin.left - margin.right;
  const height = containerHeight - margin.top - margin.bottom;

  const svg = d3.select(chartContainer.value)
    .append('svg')
    .attr('width', '100%')
    .attr('height', '100%')
    .attr('viewBox', `0 0 ${containerWidth} ${containerHeight}`)
    .attr('preserveAspectRatio', 'xMidYMid meet')
    .style('display', 'block')
    .style('margin', 'auto');

  const g = svg.append('g')
    .attr('transform', `translate(${margin.left},${margin.top})`)
    .attr('width', width)
    .attr('height', height);

  // 创建所有时间点（24小时）
  const timePoints = [];
  for (let i = 0; i <= 24; i++) {
    const hour = i.toString().padStart(2, '0');
    timePoints.push(`${hour}:00`);
  }
  
  const x = d3.scalePoint()
    .domain(timePoints)
    .range([0, width])
    .padding(0.5);

  // X轴绘制
  g.append('g')
    .attr('transform', `translate(0,${height})`)
    .call(d3.axisBottom(x)
      .tickFormat((d, i) => {
        return i % 3 === 0 ? d : '';
      })
      .tickSize(-height)
    )
    .call(g => g.select('.domain').remove())
    .call(g => g.selectAll('.tick line')
      .attr('stroke', '#e0e0e0')
      .attr('stroke-opacity', 0.3)
    )
    .call(g => g.selectAll('.tick text')
      .attr('dy', '1.0em')
      .style('font-size', `${props.axisFontSize}px`)
      .style('fill', props.bottomAxisTextColor));

  // 创建功率的Y轴比例尺
  const yPower = d3.scaleLinear()
    .domain([d3.min(props.powerData) * 1.1, d3.max(props.powerData) * 1.1])
    .range([height, 0]);

  // 创建电量的Y轴比例尺
  const yEnergy = d3.scaleLinear()
    .domain([0, d3.max(props.energyData) * 1.1])
    .range([height, 0]);

  // 绘制左侧Y轴（功率）
  g.append('g')
    .call(d3.axisLeft(yPower)
      .ticks(5)
      .tickSize(-width)
    )
    .call(g => g.select('.domain').remove())
    .call(g => g.selectAll('.tick line')
      .attr('stroke', '#e0e0e0')
      .attr('stroke-opacity', 0.3)
    )
    .call(g => g.selectAll('.tick text')
      .style('font-size', `${props.axisFontSize}px`)
      .style('fill', props.leftAxisTextColor));

  // 绘制右侧Y轴（电量）
  g.append('g')
    .attr('transform', `translate(${width},0)`)
    .call(d3.axisRight(yEnergy)
      .ticks(5)
    )
    .call(g => g.select('.domain').remove())
    .call(g => g.selectAll('.tick text')
      .style('font-size', `${props.axisFontSize}px`)
      .style('fill', props.rightAxisTextColor));

  // 计算柱状图宽度和时间点间隔
  const barWidth = width / (timePoints.length * 2);
  const timeInterval = x(timePoints[1]) - x(timePoints[0]);

  // 1. 先绘制电量柱状图
  g.selectAll('.energy-bar')
    .data(props.energyData)
    .enter()
    .append('rect')
    .attr('class', 'energy-bar')
    .attr('x', (d, i) => x(timePoints[i]) + timeInterval / 2 - barWidth / 2)
    .attr('y', d => yEnergy(d))
    .attr('width', barWidth)
    .attr('height', d => height - yEnergy(d))
    .attr('fill', props.energyBarColor)
    .attr('rx', props.energyBarBorderRadius)
    .attr('ry', props.energyBarBorderRadius)
    .style('opacity', 0.6);

  // 创建功率线条生成器
  const powerLine = d3.line()
    .x((d, i) => x(timePoints[i]))
    .y(d => yPower(d))
    .curve(props.smooth ? d3.curveMonotoneX : d3.curveLinear);

  // 2. 再绘制功率线
  g.append('path')
    .datum(props.powerData)
    .attr('class', 'power-line')
    .attr('fill', 'none')
    .attr('stroke', props.powerLineColor)
    .attr('stroke-width', props.powerLineWidth)
    .attr('d', powerLine);

  // 将鼠标交互层移到最后绘制，确保在最上层
  const mouseG = g.append('g')
    .attr('class', 'mouse-over-effects');

  // 添加透明的覆盖层用于捕获鼠标事件
  const mouseArea = mouseG.append('rect')
    .attr('width', width)
    .attr('height', height)
    .attr('fill', 'none')
    .attr('pointer-events', 'all');

  // 添加竖线
  const verticalLine = mouseG.append('line')
    .attr('class', 'mouse-line')
    .attr('y1', 0)
    .attr('y2', height)
    .style('stroke', '#666')
    .style('stroke-width', '1px')
    .style('opacity', '0');

  // 添加提示框容器
  const tooltip = mouseG.append('g')
    .attr('class', 'tooltip')
    .style('opacity', '0');

  // 添加提示框背景
  tooltip.append('rect')
    .attr('class', 'tooltip-bg')
    .attr('rx', props.tooltipBorderRadius)
    .attr('ry', props.tooltipBorderRadius)
    .attr('fill', props.tooltipBgColor)
    .attr('width', props.tooltipWidth)
    .attr('height', props.tooltipHeight);

  // 添加时间文本
  const timeText = tooltip.append('text')
    .attr('class', 'tooltip-time')
    .attr('x', props.tooltipPadding)
    .attr('y', props.tooltipPadding + props.tooltipLineHeight)
    .style('fill', props.tooltipTextColor)
    .style('font-size', `${props.tooltipFontSize}px`);

  // 添加功率文本
  const powerText = tooltip.append('text')
    .attr('class', 'tooltip-power')
    .attr('x', props.tooltipPadding)
    .attr('y', props.tooltipPadding + props.tooltipLineHeight * 2)
    .style('fill', props.tooltipTextColor)
    .style('font-size', `${props.tooltipFontSize}px`);

  // 添加电量文本
  const energyText = tooltip.append('text')
    .attr('class', 'tooltip-energy')
    .attr('x', props.tooltipPadding)
    .attr('y', props.tooltipPadding + props.tooltipLineHeight * 3)
    .style('fill', props.tooltipTextColor)
    .style('font-size', `${props.tooltipFontSize}px`);

  // 计算每个时间点的x坐标
  const timePositions = timePoints.map(time => x(time));

  // 添加鼠标移动事件处理
  mouseArea
    .on('mouseover', () => {
      verticalLine.style('opacity', '1');
      tooltip.style('opacity', '1');
    })
    .on('mouseout', () => {
      verticalLine.style('opacity', '0');
      tooltip.style('opacity', '0');
    })
    .on('mousemove', (event) => {
      const [mouseX, mouseY] = d3.pointer(event);
      
      // 找到最近的时间点
      let closestIndex = 0;
      let minDistance = Math.abs(timePositions[0] - mouseX);
      
      timePositions.forEach((pos, index) => {
        const distance = Math.abs(pos - mouseX);
        if (distance < minDistance) {
          minDistance = distance;
          closestIndex = index;
        }
      });

      // 更新竖线位置
      const xPos = timePositions[closestIndex];
      verticalLine
        .attr('x1', xPos)
        .attr('x2', xPos);

      // 获取当前点的数据
      const currentTime = timePoints[closestIndex];
      const currentPower = props.powerData[closestIndex] || 0;
      const currentEnergy = props.energyData[closestIndex] || 0;

      // 更新提示框位置和内容
      let tooltipX = xPos + 10;
      let tooltipY = mouseY - 40;

      // 防止提示框超出右边界
      if (tooltipX + props.tooltipWidth > width) {
        tooltipX = xPos - props.tooltipWidth - 10;
      }

      // 防止提示框超出上边界
      if (tooltipY < 0) {
        tooltipY = 10;
      }

      tooltip.attr('transform', `translate(${tooltipX},${tooltipY})`);
      timeText.text(`时间: ${currentTime}`);
      powerText.text(`功率: ${currentPower.toFixed(1)}${props.powerUnit}`);
      energyText.text(`电量: ${currentEnergy.toFixed(1)}${props.energyUnit}`);
    });
};

// 处理窗口大小改变事件
const handleResize = () => {
  if (!chartContainer.value) return;
  
  // 清除现有的图表
  d3.select(chartContainer.value).selectAll('*').remove();
  
  // 重新初始化图表
  nextTick(() => {
    initD3Chart();
  });
};

// 监听容器尺寸变化
const resizeObserver = new ResizeObserver(() => {
  handleResize();
});

// 监听全屏状态变化
const handleFullscreenChange = () => {
  handleResize();
};

// 组件挂载时的初始化
onMounted(() => {
  nextTick(() => {
    initD3Chart();
    // 监听容器尺寸变化
    if (chartContainer.value) {
      resizeObserver.observe(chartContainer.value);
    }
    window.addEventListener('resize', handleResize);
    // 添加全屏变化监听
    document.addEventListener('fullscreenchange', handleFullscreenChange);
    document.addEventListener('webkitfullscreenchange', handleFullscreenChange);
    document.addEventListener('mozfullscreenchange', handleFullscreenChange);
    document.addEventListener('MSFullscreenChange', handleFullscreenChange);
  });
})

// 组件卸载前的清理工作
onBeforeUnmount(() => {
  window.removeEventListener('resize', handleResize);
  if (chartContainer.value) {
    resizeObserver.disconnect();
  }
  // 移除全屏变化监听
  document.removeEventListener('fullscreenchange', handleFullscreenChange);
  document.removeEventListener('webkitfullscreenchange', handleFullscreenChange);
  document.removeEventListener('mozfullscreenchange', handleFullscreenChange);
  document.removeEventListener('MSFullscreenChange', handleFullscreenChange);
})

// 监听数据变化，更新图表
watch([() => props.powerData, () => props.energyData, () => props.timeData], () => {
  nextTick(() => {
    // 这里可以添加更新D3图表的逻辑
  });
}, { deep: true })
</script>

<style lang="scss" scoped>
.pcs-chart-card {
  width: 100%;
  height: 100%;
  background: transparent;
  transition: all 0.3s ease;
  padding: 0;
  display: flex;
  flex-direction: column;

  &.dark-theme {
    :deep(.n-card) {
      background: rgba(16, 16, 20, 0.6);
    }
  }

  :deep(.n-card-header) {
    padding: 8px 12px;
  }

  :deep(.n-card__content) {
    padding: 0;
    flex: 1;
    display: flex;
    flex-direction: column;
  }

  .chart-header {
    padding: 0;
    display: flex;
    justify-content: space-between;
    align-items: center;
    margin-bottom: 0px;
  }

  .chart-legend {
    display: flex;
    align-items: center;
    
    .legend-dot {
      width: 8px;
      height: 8px;
      border-radius: 50%;
      margin-right: 4px;
    }
  }
  
  .chart-container {
    padding: 0;
    width: 100%;
    height: 100%;
    flex: 1;
    display: flex;
    position: relative;
    overflow: visible;

    svg {
      position: absolute;
      top: 0;
      left: 0;
      right: 0;
      bottom: 0;
      width: 100%;
      height: 100%;

      .domain{
        color: purple;
        background-color: purple;
      }
    }

    .mouse-line {
      transition: opacity 0.2s ease;
    }

    .time-label {
      transition: opacity 0.2s ease;
    }
  }
}
</style>